package com.casic.ccp.flying.youth.timeseriesdata.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.ccp.flying.youth.timeseriesdata.bo.UploadFileBo;
import com.casic.ccp.flying.youth.timeseriesdata.model.DataLoadInfo;
import com.casic.ccp.flying.youth.timeseriesdata.model.SocketClient;
import com.casic.ccp.flying.youth.timeseriesdata.model.UploadFile;
import com.casic.ccp.flying.youth.timeseriesdata.result.GlobalResult;
import com.casic.ccp.flying.youth.timeseriesdata.result.ResultData;
import com.casic.ccp.flying.youth.timeseriesdata.result.ResultMessage;
import com.casic.ccp.flying.youth.timeseriesdata.service.DataLoadService;
import com.casic.ccp.flying.youth.timeseriesdata.service.FileService;
import com.casic.ccp.flying.youth.timeseriesdata.service.TaosService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ZeroCopyHttpOutputMessage;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.io.File;
import java.io.UnsupportedEncodingException;

/**
 * 文件管理接口
 *
 * @Author: 贺坤
 * @Date: 2021/9/8 16:27
 */
@Controller
@RequestMapping("/file")
public class FileController {
    /**
     * 日志记录器
     */
    private static Logger LOGGER = LoggerFactory.getLogger(FileController.class);
    /**
     * 文件管理
     */
    @Autowired
    FileService fileService;
    /**
     * 涛思数据 服务
     */
    @Autowired
    TaosService taosService;

    @Autowired
    private DataLoadService dataLoadService;

    @Autowired
    private ThreadPoolTaskExecutor taskThreadPoolTaskExecutor;

    /**
     * 接收上传的文件并存储
     *
     * @param file
     * @return
     */
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public Mono<String> add(@RequestPart("file") FilePart file) {
        // 获取当前文件名
        String filename = file.filename();
        // 得到在硬盘中的实际名称
        String storeDataFileName = fileService.save(filename);
        // 获取文件存储对象
        File storeDataFile = fileService.preparingToStoreDataFile(storeDataFileName);
        // 将文件进行存储
        Mono<Void> voidMono = file.transferTo(storeDataFile);
        QueryWrapper<UploadFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(storeDataFileName), "another_Name", storeDataFileName);
        UploadFile uploadFile = fileService.getOne(queryWrapper);
        uploadFile.setFileSize(storeDataFile.length());
        fileService.updateById(uploadFile);
        LOGGER.info("上传成功"+storeDataFile.length());
        return Mono.just(filename);
    }

    /**
     * 这是文件导入接口
     *
     * @return
     */
    @PostMapping("importData")
    @ResponseBody
    public ResultMessage importData(UploadFileBo fileBo) {
        long startTime = System.currentTimeMillis();
        UploadFile uploadFile = fileService.getById(fileBo.getId());
        DataLoadInfo dataLoadInfo = taosService.batchDataWrit(uploadFile,new SocketClient(null,null));
        long endTime = System.currentTimeMillis();
        LOGGER.info("文件:{},导入耗时{}毫秒",dataLoadInfo.getFileName(),(endTime-startTime));
        dataLoadService.save(dataLoadInfo);
        return new ResultMessage("导入成功", "success");
    }
    @GetMapping("test")
    @ResponseBody
    public String test() {
        return ""+taskThreadPoolTaskExecutor.toString();
    }

//    @GetMapping("test")
//    public Flux<String> test() {
//        Flux<String> flux =  Flux.create(sink -> senderMap.put(id, new WebSocketSender(session, sink)));
//        return flux;
//    }



    @PostMapping("deleteFile")
    @ResponseBody
    public ResultMessage deleteFile(Long id) {
        UploadFile uploadFile = fileService.getById(id);
        boolean b = fileService.removeById(id);
        ResultMessage resultMessage;
        if (b) {
            resultMessage = new ResultMessage("删除", "删除成功", "success");
            File file = new File(new File(uploadFile.getPath()), uploadFile.getAnotherName());
            file.delete();
        } else {
            resultMessage = new ResultMessage("删除", "删除失败", "error");
        }
        return resultMessage;
    }


    /**
     * 文件下载
     *
     * @param id
     * @return
     */
    @GetMapping("/downloadFile")
    @ResponseBody
    public Mono<Void> downloadFile(Long id, ServerHttpResponse response) {
        UploadFile uploadFile = fileService.getById(id);
        File file = new File(new File(uploadFile.getPath()), uploadFile.getAnotherName() + FileService.SUFFIX);
        ZeroCopyHttpOutputMessage zeroCopyResponse = (ZeroCopyHttpOutputMessage) response;
        try {
            //输出文件名乱码问题处理
            response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=" + new String(uploadFile.getName().getBytes("UTF-8"), "iso-8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.getHeaders().setContentType(MediaType.APPLICATION_OCTET_STREAM);
        Mono<Void> voidMono = zeroCopyResponse.writeWith(file, 0, file.length());
        return voidMono;
    }

    /**
     * 文件列表查询接口
     */
    @GetMapping("getFileList")
    @ResponseBody
    public GlobalResult getFileList(UploadFileBo fileBo) {
        GlobalResult globalResult = new GlobalResult();
        ResultData resultData = new ResultData();
        Page<UploadFile> page = new Page<>();
        page.setCurrent(fileBo.getPage());
        page.setSize(fileBo.getLimit());
        QueryWrapper<UploadFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(fileBo.getName()), "name", fileBo.getName());
        queryWrapper.like(!StringUtils.isEmpty(fileBo.getAnotherName()), "another_Name", fileBo.getAnotherName());
        fileService.page(page, queryWrapper);
        resultData.setTotal(page.getTotal());
        resultData.setItems(page.getRecords());
        globalResult.setCode(20000);
        globalResult.setData(resultData);
        return globalResult;
    }
}
